/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2018年5月2日
 * V4.0
 */
package com.jphenix.driver.dbshell;

import com.jphenix.share.lang.SDate;
import com.jphenix.share.lang.SDouble;
import com.jphenix.share.lang.SInteger;
import com.jphenix.share.lang.SLong;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.share.util.StringUtil;
import com.jphenix.standard.docs.ClassInfo;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

/**
 * 驱动工具类
 * com.jphenix.driver.dbshell.DriverUtil
 * 
 * 2019-04-09 用SDouble替代了SFloat
 * 
 * @author MBG
 * 2018年5月2日
 */
@ClassInfo({"2019-04-09 11:16","驱动工具类"})
public class DriverUtil {

    public static final String URL_HEADER = "jdbc:jphenix:shell:"; //数据库连接头
    
    /**
     * 返回目标数据库连接信息
     * @param url 当前URL
     * @return  0数据源主键 1目标数据库驱动类路径 2目标数据库连接URL
     * 2018年4月26日
     * @author MBG
     */
    public static String[] fixTargetInfo(String url) {
        if(url==null || !url.toLowerCase().startsWith(URL_HEADER)) {
            return null;
        }
        //构建返回值
        String[] res = new String[3];
        //去掉前缀
        url = url.substring(URL_HEADER.length());
        
        //截取当前驱动所需的配置信息，url= 后面的内容中，有可能也有 &key=value 格式的信息
        //所以得先截取出当前驱动所需的信息字符串
        int point = url.toLowerCase().indexOf("#url=");
        //目标数据库连接URL
        if(point>0) {
            res[2] = url.substring(point+5);
            url    = url.substring(0,point);
        }
        int endPoint; //截至节点
        //转换为小写，识别参数主键
        String checkUrl = url.toLowerCase();
        
        //获取数据源主键
        point = url.indexOf("source=");
        if(point>-1) {
            endPoint = checkUrl.indexOf("#",point);
            if(endPoint<0) {
                endPoint = checkUrl.length();
            }
            res[0] = url.substring(point+7,endPoint);
        }
        //获取数据源主键
        point = url.indexOf("driver=");
        if(point>-1) {
            endPoint = checkUrl.indexOf("#",point);
            if(endPoint<0) {
                endPoint = checkUrl.length();
            }
            res[1] = url.substring(point+7,endPoint);
        }
        return res;
    }
    
  
    /**
     * 判断操作语句是否为更新语句
     * @param sql    操作语句
     * @return       是否为更新语句
     * 2018年5月2日
     * @author MBG
     */
    public static boolean notQuery(String sql) {
        return sql != null && !BaseUtil.trim(sql, " ", "\t", "\r\n", "\r", "\n").toLowerCase().startsWith("select");
    }
    
    /**
     * 判断是否为新增语句
     * @param sql 操作语句
     * @return    是否为新增语句
     * 2018年5月2日
     * @author MBG
     */
    public static boolean isInsert(String sql) {
        return sql != null && BaseUtil.trim(sql, " ", "\t", "\r\n", "\r", "\n").toLowerCase().startsWith("insert");
    }
    
    /**
     * 获取指定语句中提交了多少个参数
     * @param sql 指定语句
     * @return    提交了参数个数
     * 2018年5月4日
     * @author MBG
     */
    public static int parameterCount(String sql) {
	if(sql==null) {
	    return 0;
	}
	return StringUtil.inStrCount(sql,"?");
    }
    
    /**
     * 将提交值转换为字符串信息
     * @param parameterValue 提交值对象
     * @return 字符串格式提交值
     * 2018年5月4日
     * @author MBG
     */
    public static String str(Object parameterValue) {
	if(parameterValue==null) {
	    return "";
	}
	if(parameterValue instanceof String) {
	    return (String)parameterValue;
	}
	if(parameterValue instanceof Boolean) {
	    return ((Boolean)parameterValue).booleanValue()?"1":"0";
	}
	if(parameterValue instanceof Byte) {
	    return String.valueOf(((Byte)parameterValue).intValue());
	}
	if(parameterValue instanceof byte[]) {
	    return new String((byte[])parameterValue);
	}
	if(parameterValue instanceof Date) {
	    return (new SDate(parameterValue)).getDateTime();
	}
	if(parameterValue instanceof Double) {
	    return SDouble.stringValueOf(parameterValue);
	}
	if(parameterValue instanceof Float) {
	    return SDouble.stringValueOf(parameterValue);
	}
	if(parameterValue instanceof Integer) {
	    return SInteger.stringValueOf(parameterValue);
	}
	if(parameterValue instanceof Long) {
	    return SLong.stringValueOf(parameterValue);
	}
	if(parameterValue instanceof Short) {
	    return ((Short)parameterValue).toString();
	}
	if(parameterValue instanceof Time) {
	    return (new SDate(parameterValue)).getDateTime();
	}
	if(parameterValue instanceof Timestamp) {
	    return (new SDate(parameterValue)).getTS();
	}
	return parameterValue.toString();
    }
    
    /**
     * 返回语句的操作类型（小写）
     * @param sql   操作语句
     * @return      操作类型，通常为：select update delete insert 如果为空字符串，说明语句有猫饼
     * 2018年5月2日
     * @author MBG
     */
    public static String getDealType(String sql) {
        if(sql==null || sql.length()<1) {
            return "";
        }
        //截取分割点
        int point = sql.indexOf(" ");
        if(point<0) {
            point = sql.indexOf("\t");
        }
        if(point<0) {
            point = sql.indexOf("\r");
        }
        if(point<0) {
            point = sql.indexOf("\n");
        }
        if(point>0) {
            sql = sql.substring(0,point);
        }else {
            return "";
        }
        return sql.toLowerCase();
    }
    
    
    
    /**
     * 返回更新语句的条件语句 (注意：只对update delete 有效）
     * @param sql  操作语句
     * @return     操作语句的条件语句
     * 2018年5月2日
     * @author MBG
     */
    public static String getWhere(String sql) {
        if(sql==null) {
            return "";
        }
        //将操作语句全部转换成小写
        String checkSql = sql.toLowerCase();
        int point;
        while(true) {
            point = checkSql.indexOf(" where");
            if(point<0) {
                point = checkSql.indexOf("\twhere");
            }
            if(point<0) {
                point = checkSql.indexOf("\nwhere");
            }
            if(point<0) {
                return "";
            }
            checkSql = checkSql.substring(point+6);
            sql = sql.substring(point+6);
            
            if(checkSql.startsWith(" ") 
                    || checkSql.startsWith("\t") 
                    || checkSql.startsWith("\r") 
                    || checkSql.startsWith("\n") 
                    || checkSql.startsWith("\r\n")) {
                break;
            }
        }
        return BaseUtil.trim(sql," ","\t","\r\n","\r","\n");
    }
    
    
    /**
     * 返回更新语句中的表名（注意：只能用在update insert delete语句中）
     * @param sql 更新语句
     * @return 操作的表名
     * 
     * 说明： 由于sql语句的格式比较灵活，分隔符不一定是空格，所以处理起来比较麻烦
     * 
     * 2018年5月2日
     * @author MBG
     */
    public static String getTable(String sql) {
        if(sql==null) {
            return "";
        }
        String checkSql = sql.toLowerCase();
        int point;
        int cutLength = 0;
        while(true) {
            point = checkSql.indexOf(" from");
            if(point<0) {
                point = checkSql.indexOf("\tfrom");
            }else {
                cutLength = 5;
            }
            if(point<0) {
                point = checkSql.indexOf("\nfrom");
            }else if(cutLength==0){
                cutLength = 5;
            }
            if(point<0) {
                point = checkSql.indexOf(" into");
            }else if(cutLength==0){
                cutLength = 5;
            }
            if(point<0) {
                point = checkSql.indexOf("\tinto");
            }else if(cutLength==0){
                cutLength = 5;
            }
            if(point<0) {
                point = checkSql.indexOf("\ninto");
            }else if(cutLength==0){
                cutLength = 5;
            }
            if(point<0) {
                point = checkSql.indexOf("update");
            }else if(cutLength==0){
                cutLength = 6;
            }
            if(point<0) {
                point = checkSql.indexOf("delete");
            }else if(cutLength==0){
                cutLength = 6;
            }
            if(point<0) {
                return "";
            }
            checkSql = checkSql.substring(point+cutLength);
            sql = sql.substring(point+cutLength);
            
            if(checkSql.startsWith(" ") 
                    || checkSql.startsWith("\t") 
                    || checkSql.startsWith("\r") 
                    || checkSql.startsWith("\n") 
                    || checkSql.startsWith("\r\n")) {
                break;
            }
        }
        checkSql = BaseUtil.trim(checkSql," ","\t","\r\n","\r","\n");
        sql      = BaseUtil.trim(sql," ","\t","\r\n","\r","\n");
        
        point = checkSql.indexOf(" where");
        if(point<0) {
            point = checkSql.indexOf("\twhere");
        }
        if(point<0) {
            point = checkSql.indexOf("\nwhere");
        }
        if(point>0) {
            checkSql = checkSql.substring(0,point);
            sql      = sql.substring(0,point);
        }
        checkSql = BaseUtil.trim(checkSql," ","\t","\r\n","\r","\n");
        sql      = BaseUtil.trim(sql," ","\t","\r\n","\r","\n");
        
        point = sql.indexOf(" ");
        if(point<0) {
            point = sql.indexOf("\t");
        }
        if(point<0) {
            point = sql.indexOf("\n");
        }
        if(point>0) {
            sql = sql.substring(0,point);
        }
        sql =  BaseUtil.trim(sql," ","\t","\r\n","\r","\n");
        
        point = sql.indexOf("(");
        if(point>0) {
        	sql = BaseUtil.trim(sql.substring(0,point)," ","\t","\r\n","\r","\n");
        }
        return sql;
    }
}
